#ifndef ALEATOIRE_HPP
#define ALEATOIRE_HPP

/** Fichier qui définit une classe permettant de générer des nombres
 * aléatoires.
 *
 * Dans le futur, les sources de lunières pourront être déplacées aléatoirement
 * pour créer un rendu plus réaliste (les ombres sont moins nettes). L'objet
 * défini ici permet de générer des nombres aléatoires avec une distribution
 * prédeterminée.
 *
 * @file Aleatoire.hpp
 *
 * @author Johan "Solo" Luisier
 * @date 21 Mai 2010
 */


/*
 * Générateur de nombres aléatoires avec une distribution uniforme
 * dans l'intervalle 0-1.
 */
#include <boost/random/lagged_fibonacci.hpp>

/*
 * Générateur de nombre aléatoire avec une distribution quelconque.
 */
#include <boost/random/variate_generator.hpp>

/*
 * Permet d'utiliser une distribution uniforme pour générer des
 * nombres aléatoires.
 */
#include <boost/random/uniform_real.hpp>

/** Classe permettant de tirer des nombres aléatoires dans l'intervalle
 * voulu, avec une distribution uniforme.
 *
 * La classe définie est un foncteur (càd est @e callable) et permet de générer
 * des nombres aléatoires dans l'intervalle voulu. Dans l'état actuel la
 * distribution utilisée est une distribution @e uniforme, Il faudrait
 * probablement la remplacer par une distribution gaussienne.
 *
 * @author Johan "Solo" Luisier
 * @date 21 Mai 2010
 *
 * @class Aleatoire "Aleatoire.hpp" "Algebre/Aletoire.hpp"
 */
class Aleatoire
{
public:
  Aleatoire(const double& min = 0., const double& max = 1.);
  ~Aleatoire();
  double operator()();
  double uniforme();

  const double& minimum() const;
  const double& maximum() const;

protected:

  /**
   * Valeur minimale du nombre aléatoire voulu.
   */
  double Minimum;

  /**
   * Valeur maximale du nombre aléatoire voulu.
   */
  double Maximum;

  /**
   * Génére un nombre dans l'intervalle @f$ \left[ 0, 1 \right] @f$
   * avec une distribution uniforme. La performance n'est pas trop
   * mauvaise et la "période" est de @$ \sim2^{2300000} @$, avec
   * une consommation de mémoire assez importante.
   *
   * Est statique par soucis 1) d'optimisation de la mémoire et 2) de
   * qualité des nombres aléatoires créé.
   */
  static boost::lagged_fibonacci44497 GenerateurBase;

  /**
   * Implémentation de la distribution gaussienne. Permet de générer des nombres
   * aléatoires dont la distribution est uniforme.
   */
  boost::uniform_real< double > Uniforme;

  /**
   * Générateur de nombre aléatoire qui va générer un nombre réel avec une
   * distribution <del>gaussienne</del> uniforme. Notons que le premier
   * argument du @e template est une référence, ce qui permet de n'avoir qu'une
   * instance de fibonacci.
   */
  boost::variate_generator< boost::lagged_fibonacci44497&,
                            boost::uniform_real< double > > Generateur;
};

#endif // ALEATOIRE_HPP
